import React, { forwardRef, useImperativeHandle, useRef, useState, useEffect, Fragment, PointerEvent, CSSProperties, useMemo, useContext, useCallback } from "react";
import {
    VerticalRightOutlined,
    LeftOutlined,
    RightOutlined,
    VerticalLeftOutlined,
    ExclamationCircleOutlined
} from '@ant-design/icons';
import './ExcelEditor.scss'
import { deepCloneV2, _useDebounce, generateTreeData, addTreePropertyForList, filterTree, dfsRecursive, parsePrice, isEmpty, hasCommonPrefix, dfsRecursiveFromInner, getChangeEventValue, getCheckBoxChangeEventValue, toastShort, tableCellDefaultBlockStyle, comparecomDocInstance, findNodesWithChildren, tree2List, findExcelStyleByCell, adaptDocMoneyCardinalNumberName, filterTreeByDeviceNode, checkTwoDocInstanceEquals, convertToPx, convertToHex, convertToPrimaryFF, mergeCellConfigList, defaultExcelCellStyleConfig, commonErrorMsg, commonSuccessMsg, swapListElements, findLastTreeNode, findHalfCheckedKeys, defaultColmunWidthConfigCollect, defaultDocExtraConfigInfo } from "../../../utils";
import { convertCellGroupByRowToTopicObject1, convertCellGroupByRowToTopicObject2, convertCellStyleConfigToCellFormat, convertTableCellToExcelCell, findTableDataCellListByExcelCells, generateSheetRangeGridCellData, getCellOffsetTop, getCellsBySelection, getExcelCellMaxRowIndex, getMergeCellBoundInfo, getTableDataCell, getTwoExcellCellListDiffInfo, getXAxisData, getYAxisData, mergeCellStyleConfigForTableDataCellList, processExcelCellDataList, replaceOrAddCellStyleConfigList, xAxis } from "./ExcelEditorHelper";
import { TableDataCell } from "../../../types";
import { initMergeCellBoundGroup, initTableHeader } from "./initData";
import { CellBorderInfo, CellStyleConfig, DocConfig, DocExtraConfigInfo, DocInstance, ExcelCellData, ExcelColumnFillMode, ExcelConfigType, ExcelInstance, ExcelScrollInfo, FrozenInfo, InlineStyleType, LuckySheetSelectionRange, SelectOption, SheetGridRange, SheetSelection, TopicNodeActionType, TopicType, TopicUnionRecord } from "../../../utils/types";
import comDocContext from '../../../context/DocContext';
import { initExcelBuninessContentForWorker } from "../../../utils/workerUtils";
import LoadingWapper from "../../../components/loading/LoadingWapper";
import ExcelZoomKit from "./ExcelZoomKit";
import LuckySheetWapper from "./LuckySheetWapper";
import useReSize from "../../../hooks/useResize";
import { Button, Modal } from "antd";
import ExcelEditorContextMenu from "./ExcelEditorContextMenu";
import AddTopicMoal from "../topic-sider-bar/sider-modal/AddTopicMoal";
import { processDocInstanceBeforeUpdate } from "../word-editor/editor-doc-item-generate";

interface Props {
    handleSetFocusTableCellList: Function
}

const ExcelEditorV2 = (props: Props, ref?: any) => {
    useImperativeHandle(ref, () => ({
        handleChangeMainResize,
        onDispathCellStyle,
        onDispathCellBorderStyle,
        onDispathExcelConfig,
        recommandMainProjectDevice,
        getExcelExportParams,
        handleClearCellStyle,
        getLuckySheetInstance,
        pasteCellText: pasteFocusCellText,
    }));

    const {
        comDocInstance,
        _setComDocInstance,
        comDocConfig,
        _setComDocConfig,
        comFocusTopicNode,
        _setComFocusTopicNode,
        _setComFocusTableCellList,
        _setComExcelSelectionRange,
        comExcelFormatBrushConfig,
        comFocusLayoutTopicNode,
        _setComFocusLayoutTopicNode
    } = useContext(comDocContext);

    const {
        handleSetFocusTableCellList
    } = props;

    const contextMenuRef = useRef(null);

    const addTopicModalRef = useRef(null);

    const editorContainerRef = useRef(null);

    const editorContainerResize = useReSize(editorContainerRef);

    const tempComDocInstance = useRef<DocInstance>(null);

    const loadingWapperRef1 = useRef<any>(null);
    const loadingWapperRef2 = useRef<any>(null);

    const delayHideLoadingTimer1 = useRef<any>(null);
    const delayHideLoadingTimer2 = useRef<any>(null);

    const tableData = useRef<TableDataCell[]>([]);
    const cellDataList = useRef<ExcelCellData[]>([]);

    const initExcelExtraConfig = useRef<DocExtraConfigInfo>(null);

    const [excelInitialized, setExcelInitialized] = useState<boolean>(false);

    const luckySheetWapperRef = useRef<any>(null);

    const tempSheetSelectRange = useRef<SheetGridRange>(null);

    const zoomChangeDelayTimer = useRef(null);

    const scrollChangeDelayTimer = useRef(null);

    const currentSheetLastContentRowIndex = useRef(0);

    const delaySetCellVerifayTimer = useRef(null);

    const delayerRefreshTimer = useRef(null);

    //选择的树节点操作类型
    const [currentTreeNodeActionType, setCurrentTreeNodeActionType] = useState<TopicNodeActionType>(null);

    //当前选中的topic
    const [currentSelectedTopicNode, setCurrentSelectedTopicNode] = useState<TopicType>(null);

    const tempTopicList = useRef<TopicType[]>(null);

    const excelEditorContextMenuIsOpen = useRef<boolean>(false);

    const excelSheetIsScrolling = useRef(false);

    const tempComDocConfig = useRef<DocConfig>(null);

    const [modal, contextHolder] = Modal.useModal();

    const tempTopicUnionRecordList = useRef<TopicUnionRecord[]>([]);

    const excelContainerRef = useRef(null);
    const excelContainerResize = useReSize(excelContainerRef);

    useEffect(() => {
        loadingWapperRef1.current && loadingWapperRef1.current.showLoading();
        delayHideLoadingTimer1.current = setTimeout(() => {
            loadingWapperRef1.current && loadingWapperRef1.current.hideLoading();
        }, 1000);
        return () => {
            zoomChangeDelayTimer.current && clearTimeout(zoomChangeDelayTimer.current);
            scrollChangeDelayTimer.current && clearTimeout(scrollChangeDelayTimer.current);
            delayHideLoadingTimer1.current && clearTimeout(delayHideLoadingTimer1.current);
            delaySetCellVerifayTimer.current && clearTimeout(delaySetCellVerifayTimer.current);
        }
    }, []);

    useEffect(() => {
        try {
            if (comFocusTopicNode) {
                const titleColList = tableData.current.filter(item => {
                    return item.bound[0] == 0 && !item.id.includes('-')
                })
                const tree = generateTreeData(titleColList);
                if (tree.length) {
                    let tempTree = [
                        {
                            id: '0',
                            children: tree
                        }
                    ]
                    const findTableCellTree = findNodesWithChildren(tempTree[0], comFocusTopicNode.id);
                    let findTableCellList = tree2List(findTableCellTree);
                    findTableCellList = findTableCellList.sort((a, b) => {
                        return a.bound[1] - b.bound[1]
                    })
                    if (findTableCellList.length) {
                        // toastShort('success', '已为你高亮表格区域')
                        let startRowIndex = findTableCellList[0].bound[1];
                        let endRowIndex = findTableCellList[findTableCellList.length - 1].bound[1];
                        // let newHighLightSelectRange = [[0, startRowIndex], [11, endRowIndex]];
                        let newHighLightSelectRange = {
                            row: [startRowIndex, endRowIndex],
                            column: [0, 11]
                        };
                        luckySheetWapperRef.current.handleScrollToTagetCell({ rowIndex: startRowIndex - 5 });
                        luckySheetWapperRef.current.handleSetRangeShow(newHighLightSelectRange)
                    } else {
                        // toastShort('warning', '未找到可高亮的表格区域')
                    }
                } else {
                    // toastShort('warning', '未找到可高亮的表格区域')
                }
            }
        } catch (e) {
            toastShort('error', '高亮表格功能异常')
        }
    }, [comFocusTopicNode]);

    useEffect(() => {
        if (
            comFocusLayoutTopicNode &&
            comFocusLayoutTopicNode.topic &&
            comFocusLayoutTopicNode.from !== "excel"
        ) {
            try {
                // console.log("执行----->", comFocusLayoutTopicNode)
                if (comFocusLayoutTopicNode) {
                    const titleColList = tableData.current.filter(item => {
                        return item.bound[0] == 0 && !item.id.includes('-')
                    })
                    const tree = generateTreeData(titleColList);
                    if (tree.length) {
                        let tempTree = [
                            {
                                id: '0',
                                children: tree
                            }
                        ]
                        const findTableCellTree = findNodesWithChildren(tempTree[0], comFocusLayoutTopicNode.topic.id);
                        let findTableCellList = tree2List(findTableCellTree);
                        findTableCellList = findTableCellList.sort((a, b) => {
                            return a.bound[1] - b.bound[1]
                        })
                        if (findTableCellList.length) {
                            // toastShort('success', '已为你高亮表格区域')
                            let startRowIndex = findTableCellList[0].bound[1];
                            let endRowIndex = findTableCellList[findTableCellList.length - 1].bound[1];
                            // let newHighLightSelectRange = [[0, startRowIndex], [11, endRowIndex]];
                            let newHighLightSelectRange = {
                                row: [startRowIndex, endRowIndex],
                                column: [0, 11]
                            };
                            luckySheetWapperRef.current.handleScrollToTagetCell({ rowIndex: startRowIndex - 5 });
                            luckySheetWapperRef.current.handleSetRangeShow(newHighLightSelectRange)
                        } else {
                            // toastShort('warning', '未找到可高亮的表格区域')
                        }
                    } else {
                        // toastShort('warning', '未找到可高亮的表格区域')
                    }
                }
            } catch (e) {
                toastShort('error', '高亮表格功能异常')
            }
        }
    }, [comFocusLayoutTopicNode]);

    useEffect(() => {
        if (comDocInstance.updateComponentName == 'ExcelEditor') {
            return;
        }
        console.log("表格界面收到comDocInstance--->", comDocInstance)
        refreshExcelTableData();
    }, [comDocInstance]);

    useEffect(() => {
        if (comDocConfig.updateComponentName == 'ExcelEditor') {
            return;
        }
        // console.log("表格界面收到comDocConfig--->", comDocConfig)
        const { docExtraConfigInfo } = comDocConfig;
        const excelRowLen = {};
        const excelColumnLen = {};
        const { columnWidthConfigCollect = defaultColmunWidthConfigCollect, rowHeightConfigCollect = {} } = docExtraConfigInfo;
        const { keys, values } = Object;
        const columnWidthConfigCollectValueList = values(columnWidthConfigCollect);
        const rowHeightConfigCollectValueList = values(rowHeightConfigCollect);
        const luckySheetInstance = getLuckySheetInstance();
        if (luckySheetInstance) {
            keys(rowHeightConfigCollect).forEach((rowIndex, index) => {
                excelRowLen[rowIndex] = convertToPx(rowHeightConfigCollectValueList[index].rowHeight, 'lb')
            })
            keys(columnWidthConfigCollectValueList).forEach((columnIndex, index) => {
                excelColumnLen[columnIndex] = convertToPx(columnWidthConfigCollectValueList[index].columnWidth, 'lb')
            })
            luckySheetInstance.setColumnWidth(excelColumnLen);
            luckySheetInstance.setRowHeight(excelRowLen);
        } else {
            console.log("luckySheetInstance--->不存在")
        }
        tempComDocConfig.current = { ...comDocConfig };
        refreshExcelTableData();
    }, [comDocConfig]);

    const pasteFocusCellText = (newCellText: string) => {
        const sheetSelection: SheetSelection[] = luckySheetWapperRef.current?.handleGetSelection();
        if (newCellText && newCellText.length) {
            if (sheetSelection && sheetSelection.length) {
                const newCell: ExcelCellData = {
                    r: sheetSelection[0].row[0],
                    c: sheetSelection[0].column[0],
                    m: newCellText
                }
                onCellValueChange(newCell);
            }
        } else {
            toastShort('warning', '粘贴板无内容！')
        }
    }

    const refreshExcelTableData = () => {
        tempComDocInstance.current = comDocInstance;
        if (comDocInstance.updateComponentName == 'TopicSliderBar') {
            loadingWapperRef2.current && loadingWapperRef2.current.showLoading();
            delayHideLoadingTimer2.current = setTimeout(() => {
                loadingWapperRef2.current && loadingWapperRef2.current.hideLoading();
            }, 500);
        }
        tempTopicList.current = comDocInstance.topicList;
        loadingWapperRef2.current && loadingWapperRef2.current.showLoading();
        delayHideLoadingTimer2.current = setTimeout(() => {
            loadingWapperRef2.current && loadingWapperRef2.current.hideLoading();
            refreshExcelTableDataLocal();
        }, 200);
    };

    const getExcelExportParams = () => {
        const {
            newTableData,
            newMergeCellBoundGroud,
        } = initExcelBuninessContentForWorker(
            tempComDocInstance.current,
            tempComDocConfig.current,
            initMergeCellBoundGroup,
            initTableHeader
        );
        // console.log("newTableData--->", newTableData)
        const {
            excelCellDataList,
            dataVerificationMap
        } = convertTableCellToExcelCell(newTableData, newMergeCellBoundGroud, comDocConfig);
        excelCellDataList.forEach(cell => {
            if (cell.v.bg) {
                cell.v.bg = convertToHex(cell.v.bg)
            }
            if (cell.v.fc) {
                cell.v.fc = convertToHex(cell.v.fc)
            }
            if (cell.v.ff) {
                cell.v.ff = convertToPrimaryFF(cell.v.ff);
            }
            if (cell.c == 11) {
                cell.m = '';
            }
        })
        let tempDocExtraConfigInfo = { ...tempComDocConfig.current.docExtraConfigInfo };
        tempDocExtraConfigInfo.mergeBoundInfo = newMergeCellBoundGroud;
        tempDocExtraConfigInfo.lastRowIndex = currentSheetLastContentRowIndex.current;
        let otherExpensesStartRowIndex = 0;
        let otherExpensesEndRowIndex = 0;
        excelCellDataList.forEach(cell => {
            if (cell.r > otherExpensesEndRowIndex) {
                otherExpensesEndRowIndex = cell.r;
            }
            if (cell.m == '其他费用') {
                otherExpensesStartRowIndex = cell.r;
            }
        })
        const treeData = [];
        const findTreeDataNode = (tree: any[], id: string) => {
            let findNode = null;
            tree.forEach(node => {
                if (node.id == id) {
                    findNode = node;
                } else if (node.children && node.children.length) {
                    findNode = findTreeDataNode(node.children, id);
                }
            })
            return findNode;
        }
        //组装公式
        for (let i = 0; i < currentSheetLastContentRowIndex.current; i++) {
            if (i > 4 && i < otherExpensesStartRowIndex) {
                let findCellData = newTableData.find(cell => cell.bound[0] == 1 && cell.bound[1] === i);
                const treeLevel = findCellData.serialNumber.split('.').length;
                if (treeLevel == 1) {
                    treeData.push({
                        name: findCellData.text,
                        id: findCellData.id,
                        pid: findCellData.pid,
                        cell: findCellData,
                        children: [],
                    });
                } else {
                    const findTreeNode = findTreeDataNode(treeData, findCellData.pid);
                    findTreeNode.children.push({
                        name: findCellData.text,
                        id: findCellData.id,
                        pid: findCellData.pid,
                        cell: findCellData,
                        children: [],
                    })
                }
            }
        }
        let formulaExecutionList = [];
        dfsRecursiveFromInner(treeData, (node) => {
            if (node.cell.isDeviceTopic) {
                formulaExecutionList.push({
                    cellIdList: [`D${node.cell.bound[1] + 1}`, `E${node.cell.bound[1] + 1}`],
                    targetCellId: `F${node.cell.bound[1] + 1}`,
                    type: 'multiply'
                })
            } else {
                let cellIdList = [];
                node.children.forEach(ele => {
                    cellIdList.push(`F${ele.cell.bound[1] + 1}`);
                })
                formulaExecutionList.push({
                    cellIdList: cellIdList,
                    targetCellId: `F${node.cell.bound[1] + 1}`,
                    type: 'sum'
                })
            }
        })
        let otherExpensesCellIdList = [];
        for (let i = otherExpensesStartRowIndex + 1; i < otherExpensesEndRowIndex; i++) {
            otherExpensesCellIdList.push(`F${i + 1}`)
        }
        formulaExecutionList.push({
            cellIdList: otherExpensesCellIdList,
            targetCellId: `F${otherExpensesStartRowIndex + 1}`,
            type: 'sum'
        })
        formulaExecutionList.push({
            cellIdList: [
                `F5`,
                `F${otherExpensesStartRowIndex + 1}`,
                `F${otherExpensesEndRowIndex + 1}`,
            ],
            targetCellId: `F4`,
            type: 'sum'
        })
        console.log("formulaExecutionList---->", formulaExecutionList)
        // console.log("otherExpensesStartRowIndex--->", otherExpensesStartRowIndex);
        // console.log("otherExpensesEndRowIndex--->", otherExpensesEndRowIndex);
        let exportParams = {
            excelCellDataList,
            otherExpensesStartRowIndex: otherExpensesStartRowIndex,
            otherExpensesEndRowIndex: otherExpensesEndRowIndex,
            docExtraConfigInfo: tempDocExtraConfigInfo,
            formulaExecutionList: formulaExecutionList
        }
        // console.log("exportParams--->", exportParams)
        return JSON.stringify(exportParams)
    }

    const getLuckySheetInstance = () => {
        return luckySheetWapperRef.current?.getLuckySheetInstance();
    }

    const handleChangeMainResize = (excelInstanceList: ExcelInstance[]) => {
        console.log("handleChangeMainResize--->")
        luckySheetWapperRef.current.handleResizeSheet();
    }

    const handleClearCellStyle = (focusTableCellList: TableDataCell[]) => {
        toastShort('success', '已清除单元格样式')
        const sheetSelection: SheetSelection[] = luckySheetWapperRef.current?.handleGetSelection();
        if (sheetSelection && sheetSelection.length) {
            let newCellConfigList = mergeCellConfigList(
                focusTableCellList,
                defaultExcelCellStyleConfig,
                comDocConfig.cellConfigList,
                'cellId'
            );
            let _tempDocConfig = tempComDocConfig.current;
            _tempDocConfig.cellConfigList = [...newCellConfigList];
            const { keys, values } = Object;
            keys(defaultExcelCellStyleConfig).forEach(styleType => {
                const styleValue = defaultExcelCellStyleConfig[styleType];
                const {
                    cellFormatAttr,
                    cellFormatValue
                    //@ts-ignore
                } = convertCellStyleConfigToCellFormat(styleType, styleValue);
                luckySheetWapperRef.current.handleSetRangeFormat(cellFormatAttr, cellFormatValue, tempSheetSelectRange.current);
            })
            handleUpdateComDocConfig(deepCloneV2(_tempDocConfig))
        }
    }

    useEffect(() => {
        const handleKeyDown = (event) => {
            if (event.key === 'a' && (event.ctrlKey || event.metaKey)) {
                event.preventDefault(); // 阻止默认行为
                let range = {
                    column: [0, 12],
                    row: [0, currentSheetLastContentRowIndex.current]
                }
                tempSheetSelectRange.current = range;
            }
        };
        // 添加事件监听器
        document.addEventListener('keydown', handleKeyDown);
        // 清理函数，在组件卸载时移除事件监听器
        return () => {
            document.removeEventListener('keydown', handleKeyDown);
        };
    }, []);

    const onExcelContainerMouseUp = () => {
        if (excelSheetIsScrolling.current) {
            return false;
        }
        try {
            let _tempComDocConfig: DocConfig = deepCloneV2(tempComDocConfig.current);
            const luckySheetInstance = luckySheetWapperRef.current.getLuckySheetInstance();
            const sheetSelection: SheetSelection[] = luckySheetWapperRef.current?.handleGetSelection();
            if (sheetSelection && sheetSelection.length) {
                let range: LuckySheetSelectionRange = {
                    column: sheetSelection[0]['column'],
                    row: sheetSelection[0]['row'],
                }
                const rowIndex = sheetSelection[0]['row'][0];
                const columnIndex = sheetSelection[0]['column'][0];
                const luckSheetConfig = luckySheetInstance.getConfig();
                const defaultRowHeight = 30;
                const defaultColWidth = 90;
                let columnWidth = luckSheetConfig.columnlen[columnIndex] || defaultColWidth;
                let rowHeight = luckSheetConfig.rowlen[rowIndex] || defaultRowHeight;
                range.columnWidth = columnWidth;
                range.rowHeight = rowHeight;
                _setComExcelSelectionRange(range);
                tempSheetSelectRange.current = range;
                const cells = getCellsBySelection(cellDataList.current, sheetSelection);
                const tableDataCellList = findTableDataCellListByExcelCells(tableData.current, cells);
                if (tableDataCellList && tableDataCellList.length) {
                    const newTableDataCellList = mergeCellStyleConfigForTableDataCellList(_tempComDocConfig, tableDataCellList);
                    handleSetFocusTableCellList && handleSetFocusTableCellList(newTableDataCellList)
                }
                if (comExcelFormatBrushConfig && comExcelFormatBrushConfig.enable && comExcelFormatBrushConfig.tableDataCellList && comExcelFormatBrushConfig.tableDataCellList.length) {
                    const { cellConfigList = [] } = _tempComDocConfig;
                    const { tableDataCellList } = comExcelFormatBrushConfig;
                    let excelFormatBrushBound = [];
                    let minColIndex = 999;
                    let minRowIndex = 999;
                    let maxColIndex = 0;
                    let maxRowIndex = 0;
                    tableDataCellList.forEach(cell => {
                        const cellColIndex = cell.bound[0];
                        const cellRowIndex = cell.bound[1];
                        if (cellColIndex < minColIndex) {
                            minColIndex = cellColIndex;
                        }
                        if (cellRowIndex < minRowIndex) {
                            minRowIndex = cellRowIndex;
                        }
                        if (cellColIndex > maxColIndex) {
                            maxColIndex = cellColIndex;
                        }
                        if (cellRowIndex > maxRowIndex) {
                            maxRowIndex = cellRowIndex;
                        }
                    })
                    const excelFormatBrushRowSpan = maxRowIndex - minRowIndex;
                    const excelFormatBrushColSpan = maxColIndex - minColIndex;
                    excelFormatBrushBound = [[minColIndex, minRowIndex], [maxColIndex, maxRowIndex]];
                    let currentEffectFormatBrushBound = [
                        [range.column[0], range.row[0]],
                        [range.column[0] + maxColIndex - minColIndex, range.row[0] + maxRowIndex - minRowIndex]
                    ];
                    const rowIndexOffset = currentEffectFormatBrushBound[0][1] - minRowIndex;
                    const colIndexOffset = currentEffectFormatBrushBound[0][0] - minColIndex;
                    const excelFormatBrushMaxRowIndex = currentEffectFormatBrushBound[0][1] + excelFormatBrushRowSpan;
                    const excelFormatBrushMaxColIndex = currentEffectFormatBrushBound[0][0] + excelFormatBrushColSpan;
                    let fragmentCellStyleConfigList: CellStyleConfig[] = [];
                    let needToSetCellFormatParamsList: { rowIndex: number, colIndex: number, cellFormatAttr: string, cellFormatValue: any }[] = [];
                    for (let c = currentEffectFormatBrushBound[0][0]; c <= currentEffectFormatBrushBound[1][0]; c++) {
                        for (let r = currentEffectFormatBrushBound[0][1]; r <= currentEffectFormatBrushBound[1][1]; r++) {
                            if (c <= excelFormatBrushMaxColIndex && r <= excelFormatBrushMaxRowIndex) {
                                let newCellStyleConfig: CellStyleConfig = {
                                    rowIndex: r,
                                    colIndex: c,
                                    type: 'cell',
                                };
                                const originColIndex = c - colIndexOffset;
                                const originRowIndex = r - rowIndexOffset;
                                let formatBrushTargetCell: TableDataCell = tableDataCellList.find(cell => {
                                    return cell.bound[0] == originColIndex && cell.bound[1] == originRowIndex;
                                })
                                const newCellOriginTableCellData = tableData.current.find(cell => {
                                    return cell.bound[0] == c && cell.bound[1] == r;
                                })
                                if (formatBrushTargetCell && newCellOriginTableCellData) {
                                    const formatBrushTargetCellStyleConfig: CellStyleConfig = formatBrushTargetCell.cellStyleConfig;
                                    newCellStyleConfig.cellId = `${newCellOriginTableCellData.id}-${newCellStyleConfig.colIndex}`;
                                    const styleTypeList: InlineStyleType[] = [
                                        'inlineFontFamily', 'inlineFontSize', 'inlineFontBold',
                                        'inlineFontItalic', 'inlineFontUnderLine', 'cellHorizontalAlign',
                                        'cellVerticalAlign', 'cellTextWrapMode', 'inlineFontColor',
                                        'inlineBackgroundColor'
                                    ];
                                    styleTypeList.forEach(styleType => {
                                        const styleValue: any = formatBrushTargetCellStyleConfig[styleType];
                                        if (!isEmpty(styleValue)) {
                                            const {
                                                cellFormatAttr,
                                                cellFormatValue
                                            } = convertCellStyleConfigToCellFormat(styleType, styleValue);
                                            needToSetCellFormatParamsList.push({
                                                rowIndex: r,
                                                colIndex: c,
                                                cellFormatAttr,
                                                cellFormatValue
                                            })
                                        }
                                    })
                                    newCellStyleConfig = {
                                        ...formatBrushTargetCellStyleConfig,
                                        ...newCellStyleConfig,
                                    }
                                    fragmentCellStyleConfigList.push(newCellStyleConfig);
                                }
                            }
                        }
                    }
                    needToSetCellFormatParamsList.forEach(params => {
                        const {
                            rowIndex,
                            colIndex,
                            cellFormatAttr,
                            cellFormatValue
                        } = params;
                        luckySheetWapperRef.current.handleSetCellFormat(rowIndex, colIndex, cellFormatAttr, cellFormatValue);
                    })
                    let _cellConfigList = replaceOrAddCellStyleConfigList(cellConfigList, fragmentCellStyleConfigList);
                    _tempComDocConfig.cellConfigList = _cellConfigList;
                    handleUpdateComDocConfig(deepCloneV2(_tempComDocConfig))
                }
            }
            if (tempSheetSelectRange.current) {
                const { row, column } = tempSheetSelectRange.current;
                let findCell = tableData.current.find(cell => {
                    return cell.bound[0] == column[0] && cell.bound[1] == row[0];
                });
                let findTopic = tempTopicList.current.find(topic => {
                    return topic.id === findCell.id;
                })

                if (findTopic) {
                    if (findTopic.topicType == 'device') {
                        let findTextTopic = tempTopicList.current.find(topic => {
                            return topic.id === findTopic.pid;
                        })
                        _setComFocusLayoutTopicNode({
                            from: 'excel',
                            topic: findTextTopic
                        });
                    } else {
                        _setComFocusLayoutTopicNode({
                            from: 'excel',
                            topic: findTopic
                        });
                    }
                }
            }
        } catch (e) {
            toastShort('error', '表格工具聚焦异常' + e);
        }
    }

    const onRangeSelect = (e) => {
    }

    const onCellMousedown = () => {
    }

    // {
    //     "type": "cell",
    //     "cellId": "64accf424a7e99a264c10643-1",
    //     "colIndex": 1,
    //     "rowIndex": 6,
    //     "inlineFontFamily": "宋体",
    //     "inlineFontSize": "小四",
    //     "inlineFontBold": false,
    //     "inlineFontItalic": false,
    //     "inlineFontUnderLine": false,
    //     "inlineFontSuperScript": null,
    //     "cellHorizontalAlign": "center",
    //     "cellVerticalAlign": "center",
    //     "cellTextWrapMode": "0",
    //     "inlineFontColor": "#000000",
    //     "inlineBackgroundColor": ""
    // }
    const onDispathCellStyle = (cellStyleDispacher: { styleType: InlineStyleType, styleValue: string | number }) => {
        const {
            styleType,
            styleValue
        } = cellStyleDispacher;
        // console.log("表格页面接收到----->cellStyleDispacher", cellStyleDispacher);
        if (isEmpty(tempSheetSelectRange.current)) {
            return false;
        }
        const {
            cellFormatAttr,
            cellFormatValue
        } = convertCellStyleConfigToCellFormat(styleType, styleValue);
        luckySheetWapperRef.current.handleSetRangeFormat(cellFormatAttr, cellFormatValue, tempSheetSelectRange.current);
    }

    const checkCurrentSheetSelectRangeType = (): 'cell' | 'range' | 'none' => {
        let result: 'cell' | 'range' | 'none' = 'none';
        const selectRange: SheetGridRange = tempSheetSelectRange.current;
        if (selectRange) {
            const { row, column } = selectRange;
            if (
                (
                    column.length == 2 &&
                    column[0] - column[1] > 0
                ) ||
                (
                    row.length == 2 &&
                    row[0] - row[1] > 0
                )
            ) {
                result = 'range'
            } else {
                result = 'cell'
            }
        }
        return result;
    }

    /**
     * @param cellBorderInfoList BordersLineType 枚举包含以下类型：
     * DiagonalDown：从每个单元格范围的左上角到右下角的边框。
     * DiagonalUp：从每个单元格范围的左下角到右上角的边框。
     * EdgeBottom：范围底部的边框。
     * EdgeLeft：范围左侧的边框。
     * EdgeRight：范围右侧的边框。
     * EdgeTop：范围顶部的边框​2​。
     * LineStyleType 枚举包含以下类型：
     * DashDot：虚线点线样式。
     * DashDotDot：虚线点点线样式。
     * Dashed：虚线样式。
     * Dotted：点线样式。
     * Double：双线样式。
     * Hair：细线（hairline）样式。
     * Medium：中等线样式。
     * MediumDashDot：中等虚线点线样式。
     * MediumDashDotDot：中等虚线点点线样式。
     * MediumDashed：中等虚线样式。
     * None：无线样式。
     * SlantedDashDot：倾斜的虚线点线样式。
     * Thick：粗线样式。
     * Thin：细线样式​3​。
     * @returns 
    */
    const onDispathCellBorderStyle = (cellBorderInfoList: CellBorderInfo[]) => {
        const selectRangeType = checkCurrentSheetSelectRangeType();
        if (selectRangeType == 'none') {
            return toastShort('error', '请先设定需要操作的单元格选区')
        }
        const selectRange = tempSheetSelectRange.current;
        let tempCellBorderInfoList: CellBorderInfo[] = [];
        cellBorderInfoList.forEach(cellBorderInfo => {
            let tempCellBorderInfo: CellBorderInfo = deepCloneV2(cellBorderInfo);
            tempCellBorderInfo.rangeType = 'range';
            tempCellBorderInfo.range = [selectRange];
            tempCellBorderInfoList.push(tempCellBorderInfo);
            // luckySheetWapperRef.current.handleSetRangeFormat('bd', cellBorderInfo, selectRange)
            // luckySheetWapperRef.current.handleSetRangeBorder(cellBorderInfo, { range: [selectRange] })
        })
        let _tempComDocConfig = comDocConfig;
        if (isEmpty(_tempComDocConfig.docExtraConfigInfo.borderInfo)) {
            _tempComDocConfig.docExtraConfigInfo.borderInfo = []
        }
        _tempComDocConfig.docExtraConfigInfo.borderInfo = _tempComDocConfig.docExtraConfigInfo.borderInfo.concat(tempCellBorderInfoList);
        luckySheetWapperRef.current.handleSetConfig({ borderInfo: _tempComDocConfig.docExtraConfigInfo.borderInfo });
        handleUpdateComDocConfig(_tempComDocConfig);
    }

    const onDispathExcelConfig = (excelConfigDispacher: { configType: ExcelConfigType, configValue: string }) => {
        const {
            configType,
            configValue
        } = excelConfigDispacher;
        switch (configType) {
            case 'frozenInfo':
                const frozenValueList = configValue.split('-');
                let frozenInfo: FrozenInfo = {
                    //@ts-ignore
                    type: frozenValueList[0],
                    range: {
                        row_focus: Number(frozenValueList[1]) - 1,
                        column_focus: Number(frozenValueList[2]) - 1
                    }
                }
                let _tempComDocConfig = comDocConfig;
                _tempComDocConfig.docExtraConfigInfo.frozenInfo = frozenInfo;
                handleUpdateComDocConfig(_tempComDocConfig);
                luckySheetWapperRef.current.handleSetExcelFrozen(frozenInfo);
                break;
            case 'gridInfo':
                luckySheetWapperRef.current.handleSetExcelGridSize(configValue);
                //@ts-ignore
                handleUpdateComDocConfig(configValue);
                break;
            default:
                break;
        }
    }

    const handleUpdateComDocConfig = (newDocConfig: DocConfig) => {
        let filterDoConfig = { ...newDocConfig };
        delete filterDoConfig.docExtraConfigInfo.mergeBoundInfo;
        filterDoConfig.updateComponentName = 'ExcelEditor';
        _setComDocConfig(filterDoConfig);
    }

    const onZoomChange = (e) => {
        luckySheetWapperRef.current?.handleSetZoom(e);
        if (initExcelExtraConfig.current) {
            if (zoomChangeDelayTimer.current) {
                clearTimeout(zoomChangeDelayTimer.current)
            }
            zoomChangeDelayTimer.current = setTimeout(() => {
                let _tempComDocConfig = comDocConfig;
                _tempComDocConfig.docExtraConfigInfo.zoom = e;
                handleUpdateComDocConfig(_tempComDocConfig);
            }, 1000);
        }
    }

    const makeAutoColumnWidth = () => {
        let columnWidthMap = {};
        let otherExpensesStartRowIndex = 0;
        let otherExpensesEndRowIndex = 0;
        const {
            newTableData,
            newMergeCellBoundGroud,
            topicUnionRecordList
        } = initExcelBuninessContentForWorker(
            tempComDocInstance.current,
            comDocConfig,
            initMergeCellBoundGroup,
            initTableHeader
        );
        let {
            excelCellDataList,
            // dataVerificationMap
        } = convertTableCellToExcelCell(newTableData, newMergeCellBoundGroud, comDocConfig);
        excelCellDataList.forEach(cell => {
            if (cell.r > otherExpensesEndRowIndex) {
                otherExpensesEndRowIndex = cell.r;
            }
            if (cell.m == '其他费用') {
                otherExpensesStartRowIndex = cell.r;
            }
        })
        luckySheetWapperRef.current.handleGetSheetData().forEach((rowList, rowIndex) => {
            if (rowIndex > 2 && rowIndex < otherExpensesStartRowIndex && rowList[0] && rowList[0].m) {
                for (let i = 0; i < 12; i++) {
                    const cellText = rowList[i] && rowList[i].m;
                    let textWidth = cellText && cellText.length ? cellText.length * 16 : 0;
                    if (columnWidthMap[i]) {
                        if (columnWidthMap[i] < textWidth) {
                            columnWidthMap[i] = textWidth;
                        }
                    } else {
                        columnWidthMap[i] = textWidth < 20 ? 20 : textWidth;
                    }
                }
            }
        });
        columnWidthMap[11] = 72;
        luckySheetWapperRef.current.handleSetColumnWidth(columnWidthMap)
    };

    const makeColumnFillContainer = () => {
        let containerWidth = excelContainerResize.width - 44.5 - 12;
        let columnWidthMap = {};
        for (let i = 0; i < 12; i++) {
            let columnWidth = 0;
            if (i == 0) {
                columnWidth = containerWidth * 2 * 80 / 1280;
            } else if (i == 1) {
                columnWidth = containerWidth * 4 * 80 / 1280;
            } else {
                columnWidth = containerWidth * 80 / 1280;
            }
            columnWidthMap[i] = columnWidth * 0.9181;
        }
        luckySheetWapperRef.current.handleSetColumnWidth(columnWidthMap)
    };

    const onFillMethodChange = (e: ExcelColumnFillMode) => {
        if (initExcelExtraConfig.current) {
            if (zoomChangeDelayTimer.current) {
                clearTimeout(zoomChangeDelayTimer.current)
            }
            zoomChangeDelayTimer.current = setTimeout(() => {
                let _tempComDocConfig = comDocConfig;
                _tempComDocConfig.docExtraConfigInfo.excelColumnFillMode = e;
                handleUpdateComDocConfig(_tempComDocConfig);
            }, 1000);
        }
        if (luckySheetWapperRef.current) {
            switch (e) {
                case 'autoColumnWidth':
                    makeAutoColumnWidth();
                    break;
                case 'fillContainer':
                    makeColumnFillContainer();
                    break;
                case 'fullScreen':
                    makeFullScreen();
                    break;
                default:
                    break;
            }
        }

    }

    /**
     * 单元格数据变化，主要用到 r,c,m
     * @param newCell 
     * @returns 
     */
    const onCellValueChange = (newCell: ExcelCellData) => {
        console.log("onCellValueChange-->newCell---->", newCell)
        const {
            r, //rowIndex
            c, //colIndex
            m  //新值
        } = newCell;
        if (c > 12 && !isEmpty(m)) {
            luckySheetWapperRef.current.handleSetCellValue(r, c, '');
            return toastShort('error', '投资估算表外部区域不支持填入内容')
        }
        //表格头部表头区域
        if (r <= 3 && c <= 12) {
            const findInitHeaderCell = initTableHeader.find(cell => {
                return cell.bound[0] == c && cell.bound[1] == r;
            })
            if (findInitHeaderCell && findInitHeaderCell.text !== m) {
                luckySheetWapperRef.current.handleSetCellValue(r, c, findInitHeaderCell.text);
                return toastShort('error', '此单元格内容不支持手动修改')
            }
            return;
        }
        //编号
        if (c == 0) {
            const findCellData = tableData.current.find(item => {
                return item.bound[0] == c && item.bound[1] == r;
            })
            if (findCellData && m !== findCellData.text) {
                luckySheetWapperRef.current.handleSetCellValue(r, c, findCellData.text);
                return toastShort('error', '此单元格内容不支持手动修改')
            }
        }
        //表尾总结部分
        if (
            r >= currentSheetLastContentRowIndex.current - 5 &&
            r <= currentSheetLastContentRowIndex.current
        ) {
            const findCellData = tableData.current.find(item => {
                return item.bound[0] == c && item.bound[1] == r;
            })
            if (findCellData && m !== findCellData.text) {
                luckySheetWapperRef.current.handleSetCellValue(r, c, findCellData.text);
                return toastShort('error', '此单元格内容不支持手动修改')
            }
        }
        //通过筛选条件的，就是基本可编辑的单元格。找到单元格原始数据
        const findCellData = tableData.current.find(item => {
            return item.bound[0] == c && item.bound[1] == r;
        })
        //如果有原始数据
        if (findCellData) {
            const newCellText = m.toString();
            if (c == 1) {
                //项目名称
                if (newCellText.length > 20) {
                    luckySheetWapperRef.current.handleSetCellValue(r, c, findCellData.text);
                    return toastShort('error', '长度超出20个字符')
                }
                onInputValueChange(findCellData, m)
            } else if (c == 2) {
                //单位
                if (!findCellData.isDeviceTopic) {
                    luckySheetWapperRef.current.handleSetCellValue(r, c, findCellData.text);
                    return toastShort('error', '此单元格内容不支持手动修改')
                }
                if (newCellText.length > 20) {
                    luckySheetWapperRef.current.handleSetCellValue(r, c, findCellData.text);
                    return toastShort('error', '长度超出20个字符')
                }
                //单位
                onInputValueChange(findCellData, m)
            } else if (c == 3) {
                //数量
                if (!findCellData.isDeviceTopic) {
                    luckySheetWapperRef.current.handleSetCellValue(r, c, findCellData.text);
                    return toastShort('error', '此单元格内容不支持手动修改')
                }
                const re = /^[+]{0,1}(\d+)$/;
                const cellText = m.toString();
                if (!re.test(cellText)) {
                    toastShort('warning', '只能输入正整数');
                    luckySheetWapperRef.current.handleSetCellValue(r, c, findCellData.text);
                    return false;
                }
                //数量
                onInputValueChange(findCellData, cellText)
            } else if (c == 4) {
                //单价
                if (!findCellData.isDeviceTopic) {
                    luckySheetWapperRef.current.handleSetCellValue(r, c, findCellData.text);
                    return toastShort('error', '此单元格内容不支持手动修改')
                }
                const re = /^[+]{0,1}(\d+)$|^[+]{0,1}(\d+\.\d+)$/;
                const cellText = m.toString();
                if (!re.test(cellText)) {
                    toastShort('warning', '请输入正确的数值')
                    luckySheetWapperRef.current.handleSetCellValue(r, c, findCellData.text);
                    return false;
                }
                //单价
                onInputValueChange(findCellData, m)
            } else if (c == 5) {
                if (!findCellData.isDeviceTopic) {
                    luckySheetWapperRef.current.handleSetCellValue(r, c, findCellData.text);
                    return toastShort('error', '此单元格内容不支持手动修改')
                }
                //投资金额
                luckySheetWapperRef.current.handleSetCellValue(r, c, findCellData.text);
                return toastShort('error', '此单元格内容不支持手动修改')
            } else if (
                c == 6 ||
                c == 7 ||
                c == 8
            ) {
                //建安工程、设备、其他
                //如果不是设备节点，则不支持修改内容
                if (!findCellData.isDeviceTopic) {
                    luckySheetWapperRef.current.handleSetCellValue(r, c, findCellData.text);
                    return toastShort('error', '此单元格内容不支持手动修改')
                }
                //建安工程、设备、其他
                onClickCellSwitch(findCellData);
            } else if (c == 9) {
                if (!findCellData.isDeviceTopic) {
                    luckySheetWapperRef.current.handleSetCellValue(r, c, findCellData.text);
                    return toastShort('error', '此单元格内容不支持手动修改, 请尝试修改项目投资分期金额比例')
                }
                //近期
                onInputValueChange(findCellData, m)
            } else if (c == 10) {
                if (!findCellData.isDeviceTopic) {
                    luckySheetWapperRef.current.handleSetCellValue(r, c, findCellData.text);
                    return toastShort('error', '此单元格内容不支持手动修改, 请尝试修改项目投资分期金额比例')
                }
                //中长期
                onInputValueChange(findCellData, m);
            } else if (c == 11) {
                if (!findCellData.isDeviceTopic) {
                    luckySheetWapperRef.current.handleSetCellValue(r, c, findCellData.text);
                    return toastShort('error', '此单元格内容不支持手动修改')
                }
                const currentCellText = m ? m + '' : '';
                if (!['是', '否'].includes(currentCellText)) {
                    luckySheetWapperRef.current.handleSetCellValue(r, c, findCellData.text);
                    return toastShort('error', '此单元格内容仅支持填入是/否')
                }
                //重点工程勾选与否
                onCellCheckedChange(findCellData, currentCellText == '是' ? true : false);
            } else if (c == 12) {
                //中长期
                onInputValueChange(findCellData, m);
            }
        }
    }

    const onInputValueChange = (cell: TableDataCell, value: string | number) => {
        console.log("onInputValueChange--->", cell, value)
        let _tempComDocInstance = tempComDocInstance.current;
        let tempTopicList = _tempComDocInstance.topicList;
        let needToReplaceMergedTopic = false;
        if (cell.isDeviceTopic) {
            let findTopic = tempTopicList.find(topic => topic.id == cell.id);
            if (findTopic.topicType === 'text') {
                needToReplaceMergedTopic = true;
            }
        }
        try {
            value = value.toString();
            //表格数据
            let tempTableData: Array<TableDataCell> = tableData.current;

            const currentCellGroupByRow = tempTableData.filter(item => {
                return item.bound[1] == cell.bound[1];
            })
            console.log("currentCellGroupByRow-->", deepCloneV2(currentCellGroupByRow))
            if (cell && ['nearFutureMoneyRate', 'mediumAndLongTermMoneyRate'].includes(cell.serviceType)) {
                console.log("近期中长期互相计算2", currentCellGroupByRow)
                //找到总金额
                const switchTotalValueCell = currentCellGroupByRow.find(item => {
                    return item.serviceType && item.serviceType == 'investmentCompositionMoney';
                })
                if (switchTotalValueCell && Number(switchTotalValueCell.text) < Number(value)) {
                    toastShort('warning', '金额超出')
                    return false;
                }
                currentCellGroupByRow.forEach(item => {
                    if (item.type == 'input' && ['nearFutureMoneyRate', 'mediumAndLongTermMoneyRate'].includes(item.serviceType)) {
                        if (cell.bound.toString() == item.bound.toString()) {
                            item.text = value;
                        } else {
                            item.text = (Number(switchTotalValueCell?.text) - Number(value)).toFixed(2);
                        }
                    }
                })
                const { newTopicList, needToUpdateTopicList } = updateCellGroupByRowToTopic2(currentCellGroupByRow, tempTopicList);
                tempTopicList = [...newTopicList]
            } else if (cell && ['unit', 'unitPrice', 'count'].includes(cell.serviceType)) {
                console.log("单位-单价-数量变更")
                var intPatrn = /^[0-9]*$/;
                if (cell.serviceType == 'count') {
                    if (value.includes('.') || !intPatrn.test(value)) {
                        toastShort("warning", "请输入整数");
                        return false;
                    }
                }
                currentCellGroupByRow.forEach(item => {
                    if (cell.bound.toString() == item.bound.toString()) {
                        item.text = value;
                    }
                })
                //三个基本信息的修改，都更新一遍商品总价、以及建安、设备、其他、近期、中长期的数据
                const { newTopicList, needToUpdateTopicList } = updateCellGroupByRowToTopic1(currentCellGroupByRow, tempTopicList);
                tempTopicList = [...newTopicList];
                let newTopic = needToUpdateTopicList.find(topic => topic.id == currentCellGroupByRow[0].id)
                currentCellGroupByRow.forEach((item, index) => {
                    switch (index) {
                        //投资金额
                        case 5:
                            item.text = parsePrice(newTopic.investmentCompositionMoney);
                            break;
                        //建安工程
                        case 6:
                            item.text = newTopic.investmentCompositionMoney && newTopic.investmentCompositionType == 'buildingInstallation' ?
                                parsePrice(newTopic.investmentCompositionMoney) : 0
                            break;
                        //设备
                        case 7:
                            item.text = newTopic.investmentCompositionMoney && newTopic.investmentCompositionType == 'device' ?
                                parsePrice(newTopic.investmentCompositionMoney) : 0
                            break;
                        //其他
                        case 8:
                            item.text = newTopic.investmentCompositionMoney && newTopic.investmentCompositionType == 'other' ?
                                parsePrice(newTopic.investmentCompositionMoney) : 0;
                            break;
                        //近期
                        case 9:
                            item.text = newTopic.topicType == 'device' && newTopic.investmentCompositionMoney && newTopic.nearFutureMoneyRate ?
                                parsePrice(Number(newTopic.investmentCompositionMoney) * (Number(newTopic.nearFutureMoneyRate) / 100))
                                :
                                0
                            break;
                        //中长期
                        case 10:
                            item.text = newTopic.topicType == 'device' && newTopic.investmentCompositionMoney && newTopic.mediumAndLongTermMoneyRate ?
                                parsePrice(Number(newTopic.investmentCompositionMoney) * (Number(newTopic.mediumAndLongTermMoneyRate) / 100))
                                :
                                0
                            break;
                        default:
                            break;
                    }
                })
            } else {
                if (cell.bound[0] == 12) {
                }
            }
            const {
                newTableData,
                newTopicList
            } = calculateTableOnInputValueChange(cell, value, tempTopicList);
            newTopicList.forEach(topic => {
                if (topic.topicType == 'device') {
                    if (topic.nearFutureMoneyRate == Infinity) {
                        topic.nearFutureMoneyRate = Number((Number(topic.nearFutureMoneyRateOfValue) / (Number(topic.mediumAndLongTermMoneyRateOfValue) + Number(topic.nearFutureMoneyRateOfValue)) * 100).toFixed(2))
                    }
                    if (topic.mediumAndLongTermMoneyRate == Infinity) {
                        topic.mediumAndLongTermMoneyRate = Number((Number(topic.mediumAndLongTermMoneyRateOfValue) / (Number(topic.mediumAndLongTermMoneyRateOfValue) + Number(topic.nearFutureMoneyRateOfValue)) * 100).toFixed(2))
                    }
                }
            })
            tempTopicList = [...newTopicList];
            tempTableData = [...newTableData];
            const currentCellGroupByRow2 = tempTableData.filter(item => {
                return item.bound[1] == cell.bound[1];
            })
            currentCellGroupByRow2.forEach(item => {
                if (item.type == 'input' && item.valueType == 'number' && ['unitPrice', 'investmentCompositionMoney'].includes(item.serviceType)) {
                    item.text = Number(item.text).toFixed(2);
                }
            })
            if (needToReplaceMergedTopic) {
                let needToRepalceTopicList: TopicType[] = [];
                const textTopic = tempTopicList.find(topic => topic.id == cell.id);
                const deviceTopic = tempTopicList.filter(topic => topic.pid == cell.id)[0];
                console.log("textTopic---->", deepCloneV2(textTopic));
                console.log("deviceTopic---->", deepCloneV2(deviceTopic));
                const {
                    topicName,
                    unit,
                    unitPrice,
                    _unitPrice,
                    count,
                    investmentCompositionType,
                    investmentCompositionMoney,
                    nearFutureMoneyRate,
                    mediumAndLongTermMoneyRate,
                    nearFutureMoneyRateOfValue,
                    mediumAndLongTermMoneyRateOfValue,
                    isMainProjectChcked,
                    isMainProject,
                } = textTopic;
                let newTopicList = tempTopicList.map(topic => {
                    let findReplaceTopic = needToRepalceTopicList.find(ele => ele.id == topic.id)
                    if (findReplaceTopic) {
                        return deepCloneV2(findReplaceTopic);
                    }
                    return topic;
                })
                tempTopicList = deepCloneV2(newTopicList);
            }
            tempComDocInstance.current.topicList = tempTopicList;
            handleSaveTableData(tempTableData)
            refreshExcelTableDataLocal();
            handleUpdateComDocInstance(tempComDocInstance.current);
        } catch (e) {
            toastShort('error', '操作失败' + e)
        }
    };

    const calculateTableOnInputValueChange = (
        cell: TableDataCell,
        value: string,
        tempTopicList: TopicType[]
    ): {
        newTableData: TableDataCell[],
        newTopicList: TopicType[]
    } => {
        let tempTableData: Array<TableDataCell> = tableData.current;
        const currentCellGroupByRow = tempTableData.filter(item => {
            return item.bound[1] == cell.bound[1];
        })
        if (cell && ['nearFutureMoneyRate', 'mediumAndLongTermMoneyRate'].includes(cell.serviceType)) {
            console.log("近期中长期互相计算1", currentCellGroupByRow)
            //找到总金额
            const switchTotalValueCell = currentCellGroupByRow.find(item => {
                return item.serviceType && item.serviceType == 'investmentCompositionMoney';
            })
            if (switchTotalValueCell && Number(switchTotalValueCell.text) < Number(value)) {
                toastShort('warning', '金额超出')
                return {
                    newTableData: tempTableData,
                    newTopicList: tempTopicList
                };
            }
            currentCellGroupByRow.forEach(item => {
                if (item.type == 'input' && ['nearFutureMoneyRate', 'mediumAndLongTermMoneyRate'].includes(item.serviceType)) {
                    if (cell.bound.toString() == item.bound.toString()) {
                        item.text = value;
                    } else {
                        item.text = (Number(switchTotalValueCell?.text) - Number(value)).toFixed(2);
                    }
                }
            })
            const { newTopicList, needToUpdateTopicList } = updateCellGroupByRowToTopic2(currentCellGroupByRow, tempTopicList);
            tempTopicList = newTopicList;
        } else if (cell && ['unit', 'unitPrice', 'count'].includes(cell.serviceType)) {
            var intPatrn = /^[0-9]*$/;
            if (cell.serviceType == 'count') {
                if (value.includes('.') || !intPatrn.test(value)) {
                    toastShort("warning", "请输入整数");
                    return {
                        newTableData: tempTableData,
                        newTopicList: tempTopicList
                    };
                }
            }
            currentCellGroupByRow.forEach(item => {
                if (cell.bound.toString() == item.bound.toString()) {
                    item.text = value;
                }
            })
            //三个基本信息的修改，都更新一遍商品总价、以及建安、设备、其他、近期、中长期的数据
            const { needToUpdateTopicList, newTopicList } = updateCellGroupByRowToTopic1(currentCellGroupByRow, tempTopicList);
            tempTopicList = newTopicList;
            let newTopic = needToUpdateTopicList.find(topic => topic.id == currentCellGroupByRow[0].id)
            currentCellGroupByRow.forEach((item, index) => {
                switch (index) {
                    //投资金额
                    case 5:
                        item.text = parsePrice(newTopic.investmentCompositionMoney);
                        break;
                    //建安工程
                    case 6:
                        item.text = newTopic.investmentCompositionMoney && newTopic.investmentCompositionType == 'buildingInstallation' ?
                            parsePrice(newTopic.investmentCompositionMoney) : 0
                        break;
                    //设备
                    case 7:
                        item.text = newTopic.investmentCompositionMoney && newTopic.investmentCompositionType == 'device' ?
                            parsePrice(newTopic.investmentCompositionMoney) : 0
                        break;
                    //其他
                    case 8:
                        item.text = newTopic.investmentCompositionMoney && newTopic.investmentCompositionType == 'other' ?
                            parsePrice(newTopic.investmentCompositionMoney) : 0
                        break;
                    //近期
                    case 9:
                        item.text = newTopic.topicType == 'device' && newTopic.investmentCompositionMoney && newTopic.nearFutureMoneyRate ?
                            parsePrice(Number(newTopic.investmentCompositionMoney) * (Number(newTopic.nearFutureMoneyRate) / 100))
                            :
                            0
                        break;
                    //中长期
                    case 10:
                        item.text = newTopic.topicType == 'device' && newTopic.investmentCompositionMoney && newTopic.mediumAndLongTermMoneyRate ?
                            parsePrice(Number(newTopic.investmentCompositionMoney) * (Number(newTopic.mediumAndLongTermMoneyRate) / 100))
                            :
                            0
                        break;
                    default:
                        break;
                }
            })
        } else {
            if (cell.bound[0] == 1) {
                currentCellGroupByRow.forEach(item => {
                    if (cell.bound.toString() == item.bound.toString()) {
                        item.text = value;
                    }
                })
                const { needToUpdateTopicList, newTopicList } = updateCellGroupByRowToTopic1(currentCellGroupByRow, tempTopicList);
                tempTopicList = newTopicList;
                let newTopic = needToUpdateTopicList.find(topic => topic.id == currentCellGroupByRow[0].id)
                newTopic.title = value;
                currentCellGroupByRow.forEach((item, index) => {
                    if (index == 1) {
                        item.text = value;
                    }
                })
            } else if (cell.bound[0] == 12) {
                currentCellGroupByRow.forEach(item => {
                    if (cell.bound.toString() == item.bound.toString()) {
                        item.text = value;
                    }
                })
                const { needToUpdateTopicList, newTopicList } = updateCellGroupByRowToTopic1(currentCellGroupByRow, tempTopicList);
                let newTopic = needToUpdateTopicList.find(topic => topic.id == currentCellGroupByRow[0].id)
                tempTopicList = newTopicList;
                newTopic.remark = value;
                currentCellGroupByRow.forEach((item, index) => {
                    if (index == 12) {
                        item.text = value;
                    }
                })
            }
        }
        return {
            newTableData: tempTableData,
            newTopicList: tempTopicList
        };
    }

    const updateCellGroupByRowToTopic1 = (
        cellGroupByRow: TableDataCell[],
        tempTopicList: TopicType[]
    ): {
        newTopicList: TopicType[],
        needToUpdateTopicList: TopicType[]
    } => {
        try {
            const needToUpdateTopicList = convertCellGroupByRowToTopicObject1(cellGroupByRow, tempTopicList, comDocConfig);
            let newTopicList = tempTopicList.map(topic => {
                let find = needToUpdateTopicList.find(item => item.id == topic.id);
                if (find) {
                    return find;
                }
                return topic;
            })
            return {
                needToUpdateTopicList,
                newTopicList
            };
        } catch (e) {
            console.log("单元格数据变化更新topic节点失败--->", e)
        }
    }

    const updateCellGroupByRowToTopic2 = (
        cellGroupByRow: TableDataCell[],
        tempTopicList: TopicType[]
    ): {
        needToUpdateTopicList: TopicType[],
        newTopicList: TopicType[],
    } => {
        try {
            const needToUpdateTopicList = convertCellGroupByRowToTopicObject2([...cellGroupByRow], tempTopicList);
            console.log("newTopic---->", needToUpdateTopicList)
            let newTopicList = tempTopicList.map(topic => {
                let find = needToUpdateTopicList.find(item => item.id == topic.id);
                if (find) {
                    return find;
                }
                return topic;
            })
            return {
                needToUpdateTopicList,
                newTopicList
            };
        } catch (e) {
            console.log("单元格数据变化更新topic节点失败--->", e)
        }
    }

    const onClickCellSwitch = (cell: TableDataCell): void => {
        if (cell && cell.id) {
            let _tableData: Array<TableDataCell> = tableData.current;
            const currentCellGroupByRow = _tableData.filter(item => {
                return item.bound[1] == cell.bound[1];
            })
            const switchTotalValueCell = currentCellGroupByRow.find(item => {
                return item.serviceType && item.serviceType == 'investmentCompositionMoney';
            })
            currentCellGroupByRow.forEach(item => {
                if (item.type == 'switch') {
                    if (Number(item.text) == 0 && cell.bound.toString() == item.bound.toString()) {
                        item.text = switchTotalValueCell?.text + '';
                    } else if (item.type == 'switch') {
                        item.text = 0;
                    }
                }
            })
            const { needToUpdateTopicList, newTopicList } = updateCellGroupByRowToTopic1(currentCellGroupByRow, tempComDocInstance.current.topicList);
            handleSaveTableData(_tableData);
            tempComDocInstance.current.topicList = [...newTopicList];
            handleUpdateComDocInstance(tempComDocInstance.current);
            refreshExcelTableDataLocal();
        }
    };


    const onCellCheckedChange = (tableDataCell: TableDataCell, checked: boolean) => {
        let _tableData: Array<TableDataCell> = tableData.current;
        let _tempComDocInstance = tempComDocInstance.current;
        const currentCellGroupByRow = _tableData.filter(item => {
            return item.bound[1] == tableDataCell.bound[1];
        })
        currentCellGroupByRow.forEach(cell => {
            if (cell.bound.toString() == tableDataCell.bound.toString()) {
                console.log("cell---->", cell)
                cell.isChecked = checked;
            }
        })
        const findTopic = _tempComDocInstance.topicList.find(topic => {
            return topic.id == tableDataCell.id;
        })
        if (findTopic) {
            findTopic.isMainProjectChcked = checked;
        }
        handleSaveTableData(_tableData)
        tempComDocInstance.current = _tempComDocInstance;
        handleUpdateComDocInstance(tempComDocInstance.current);
    };

    const handleSaveTableData = (newTableData: Array<TableDataCell>) => {
        tableData.current = [...newTableData];
    }

    const handleUpdateComDocInstance = (newComDocInstance: DocInstance) => {
        let _newComDocInstance = processDocInstanceBeforeUpdate(newComDocInstance);
        _newComDocInstance.updateComponentName = 'ExcelEditor';
        _setComDocInstance({ ..._newComDocInstance });
    }

    const onSheetScrollEnd = (e: ExcelScrollInfo) => {
        excelSheetIsScrolling.current = true;
        // let _tempComDocConfig = comDocConfig;
        // _tempComDocConfig.docExtraConfigInfo.scrollInfo = e;
        // tempComDocConfig.current = {..._tempComDocConfig};
        // initExcelExtraConfig.current.scrollInfo = e;
        if (scrollChangeDelayTimer.current) {
            clearTimeout(scrollChangeDelayTimer.current);
        }
        scrollChangeDelayTimer.current = setTimeout(() => {
            excelSheetIsScrolling.current = false;
            // handleUpdateComDocConfig(tempComDocConfig.current);
        }, 500);
    }

    const recommandMainProjectDevice = () => {
        const hasRecommandMainProject = comDocConfig.docExtraConfigInfo.hasRecommandMainProject;
        if (hasRecommandMainProject) {
            modal.confirm({
                title: '温馨提示',
                icon: <ExclamationCircleOutlined />,
                content: '您已推荐重点工程, 若重新推荐您已做出的重点工程相关修改会被重置，确认是否继续？',
                okText: '确认',
                cancelText: '取消',
                centered: true,
                onOk: comfirmToRecommandMainProjectDevice,
            });
        } else {
            comfirmToRecommandMainProjectDevice();
        }
    }

    const comfirmToRecommandMainProjectDevice = () => {
        luckySheetWapperRef.current.handleSetSelection("L2:L699")
        luckySheetWapperRef.current.handleScrollSheet({ targetColumn: 3 })
        setTimeout(() => {
            toastShort('success', '已推荐重点工程')
            let _tempComDocInstance = tempComDocInstance.current;
            let _tempComDocConfig = tempComDocConfig.current;
            let _tempTopicList = _tempComDocInstance.topicList;
            _tempTopicList.forEach(topic => {
                if (
                    topic.mainProjectRecommand &&
                    topic.checked == true
                ) {
                    topic.isMainProjectChcked = true;
                }
            })
            _tempComDocInstance.topicList = deepCloneV2(_tempTopicList);
            _tempComDocConfig.docExtraConfigInfo.hasRecommandMainProject = true;
            tempComDocConfig.current = _tempComDocConfig;
            tempComDocInstance.current = _tempComDocInstance;
            refreshExcelTableDataLocal();
            handleUpdateComDocConfig(tempComDocConfig.current);
            handleUpdateComDocInstance(tempComDocInstance.current);
        }, 100);
    }

    const refreshExcelTableDataLocal = () => {
        delayerRefreshTimer.current && clearTimeout(delayerRefreshTimer.current);
        delayerRefreshTimer.current = setTimeout(() => {
            const {
                newTableData,
                newMergeCellBoundGroud,
                topicUnionRecordList
            } = initExcelBuninessContentForWorker(
                tempComDocInstance.current,
                comDocConfig,
                initMergeCellBoundGroup,
                initTableHeader
            );
            console.log("topicUnionRecordList---->", topicUnionRecordList)
            tempTopicUnionRecordList.current = topicUnionRecordList;
            let {
                excelCellDataList,
                // dataVerificationMap
            } = convertTableCellToExcelCell(newTableData, newMergeCellBoundGroud, comDocConfig);
            excelCellDataList = processExcelCellDataList(excelCellDataList, comDocConfig);
            let tempMergeMap = {};
            newMergeCellBoundGroud.forEach(mergeBound => {
                tempMergeMap[`${mergeBound.focusCellbound[1]}_${mergeBound.focusCellbound[0]}`] = {
                    r: mergeBound.focusCellbound[1],
                    c: mergeBound.focusCellbound[0],
                    rs: (mergeBound.bounds[1][1] - mergeBound.bounds[0][1]) + 1,
                    cs: (mergeBound.bounds[1][0] - mergeBound.bounds[0][0]) + 1
                }
            })
            if (excelInitialized) {
                const clearRange = {
                    row: [0, currentSheetLastContentRowIndex.current],
                    column: [0, 11]
                }
                luckySheetWapperRef.current.handleClearRangeValue(clearRange);
                let gridCellDataList = luckySheetWapperRef.current.handleTransCellDataListToGridDataList(excelCellDataList);
                const allRange = {
                    row: [0, 699],
                    column: [0, 29],
                }
                if (currentSheetLastContentRowIndex.current > 3) {
                    const lastMergeRange1 = {
                        row: [currentSheetLastContentRowIndex.current - 5, currentSheetLastContentRowIndex.current - 5],
                        column: [2, 4],
                    }
                    const lastMergeRange2 = {
                        row: [currentSheetLastContentRowIndex.current - 4, currentSheetLastContentRowIndex.current - 4],
                        column: [2, 4],
                    }
                    const lastMergeRange3 = {
                        row: [currentSheetLastContentRowIndex.current - 3, currentSheetLastContentRowIndex.current - 3],
                        column: [2, 4],
                    }
                    const lastMergeRange4 = {
                        row: [currentSheetLastContentRowIndex.current - 2, currentSheetLastContentRowIndex.current - 2],
                        column: [2, 4],
                    }
                    const lastMergeRange5 = {
                        row: [currentSheetLastContentRowIndex.current - 1, currentSheetLastContentRowIndex.current - 1],
                        column: [2, 4],
                    }
                    const lastMergeRange6 = {
                        row: [currentSheetLastContentRowIndex.current, currentSheetLastContentRowIndex.current],
                        column: [2, 4],
                    }
                    luckySheetWapperRef.current.handleCancelRangeMerge(lastMergeRange1);
                    luckySheetWapperRef.current.handleCancelRangeMerge(lastMergeRange2);
                    luckySheetWapperRef.current.handleCancelRangeMerge(lastMergeRange3);
                    luckySheetWapperRef.current.handleCancelRangeMerge(lastMergeRange4);
                    luckySheetWapperRef.current.handleCancelRangeMerge(lastMergeRange5);
                    luckySheetWapperRef.current.handleCancelRangeMerge(lastMergeRange6);
                } else {
                    console.log("跳过取消合并")
                }
                luckySheetWapperRef.current.handleSetRangeValue(gridCellDataList, allRange);
                luckySheetWapperRef.current.forceRefreshWorkBook();
                currentSheetLastContentRowIndex.current = getExcelCellMaxRowIndex(excelCellDataList);
            } else {
                currentSheetLastContentRowIndex.current = getExcelCellMaxRowIndex(excelCellDataList);
            }
            cellDataList.current = excelCellDataList;
            let _initExcelExtraConfig: DocExtraConfigInfo = comDocConfig.docExtraConfigInfo;
            _initExcelExtraConfig.mergeBoundInfo = tempMergeMap;
            if (comDocConfig.docExtraConfigInfo && comDocConfig.docExtraConfigInfo.frozenInfo) {
                _initExcelExtraConfig.frozenInfo = comDocConfig.docExtraConfigInfo.frozenInfo;
            }
            initExcelExtraConfig.current = _initExcelExtraConfig;
            setExcelInitialized(true);
            handleSaveTableData(newTableData);
        }, 200);
    }

    const delaySetCellVerifay = (dataVerificationMap: any) => {
        // if(delaySetCellVerifayTimer.current){
        //     clearTimeout(delaySetCellVerifayTimer.current)
        // }
        // delaySetCellVerifayTimer.current = setTimeout(() => {
        //     luckySheetWapperRef.current.handleDeleteDataVerification({ range: clearRange });
        //     const { keys, values } = Object;
        //     const dataVerificationKeyList = keys(dataVerificationMap);
        //     dataVerificationKeyList.forEach((key, keyIndex) => {
        //         const dataVerificationRange: SheetGridRange = {
        //             row: [Number(key.split('_')[0]), Number(key.split('_')[0])],
        //             column: [Number(key.split('_')[1]), Number(key.split('_')[1])]
        //         }
        //         luckySheetWapperRef.current.handleSetDataVerification(dataVerificationMap[key], { range: dataVerificationRange })
        //     })
        // }, 1000);
    }

    const onExcelContextMenu = (e: any) => {
        if (excelEditorContextMenuIsOpen.current) {
            excelEditorContextMenuIsOpen.current = false;
            contextMenuRef.current.hideContextMenu();
            return false;
        }
        const sheetSelection: SheetSelection[] = luckySheetWapperRef.current?.handleGetSelection();
        e.clientX = e.clientX - 280;
        e.clientY = e.clientY - 130;
        excelEditorContextMenuIsOpen.current = !excelEditorContextMenuIsOpen.current;
        let rowIndex = 0;
        if (sheetSelection) {
            rowIndex = sheetSelection[0].row[0];
        }
        if (rowIndex) {
            const cellList = tableData.current.filter(cell => {
                return cell.bound[1] == rowIndex;
            })
            const topicNodeId = cellList[0].id;
            const currentNode = tempTopicList.current.find(ele => {
                return ele.id == topicNodeId;
            })
            setCurrentSelectedTopicNode(currentNode);
            if (topicNodeId) {
                console.log("开启--->")
                contextMenuRef.current.showContextMenu(e);
            }
        }
    }

    const moveNode = (nodeList: TopicType[], targetId: string, direction: 'up' | 'down' | 'top' | 'bottom'): TopicType[] => {
        let findIndex = -1;
        if (nodeList.length == 0 || nodeList.length == 1) {
            return nodeList;
        }
        for (let i = 0; i < nodeList.length; i++) {
            if (nodeList[i].id == targetId) {
                findIndex = i;
                break;
            }
        }
        if (findIndex > -1) {
            const targetNodePid = nodeList[findIndex].pid;
            switch (direction) {
                case 'top':
                    let currentChildrenNodeIndexList: number[] = [];
                    for (let i = 0; i < nodeList.length; i++) {
                        if (nodeList[i].pid == targetNodePid) {
                            if (i <= findIndex) {
                                currentChildrenNodeIndexList.push(i)
                            }
                        }
                    }
                    if (currentChildrenNodeIndexList[0] == findIndex) {
                        toastShort('warning', '该节点已置顶')
                    } else {
                        toastShort('success', commonSuccessMsg)
                        let _nodeList = nodeList;
                        for (let i = currentChildrenNodeIndexList.length - 1; i > 0; i--) {
                            const currentNodeIndex = currentChildrenNodeIndexList[i];
                            const currentNodeBeforeIndex = currentChildrenNodeIndexList[i - 1];
                            _nodeList = swapListElements(_nodeList, currentNodeBeforeIndex, currentNodeIndex);
                        }
                        return _nodeList;
                    }
                    break;
                case 'bottom':
                    let currentBottomNode = findLastTreeNode(nodeList, (ele) => {
                        return ele.pid == targetNodePid;
                    })
                    let currentBottomNodeIndex = -1;
                    for (let i = 0; i < nodeList.length; i++) {
                        if (nodeList[i].id == currentBottomNode.id) {
                            currentBottomNodeIndex = i;
                            break;
                        }
                    }
                    if (currentBottomNodeIndex == findIndex) {
                        toastShort('warning', '该节点已置底')
                    } else {
                        toastShort('success', commonSuccessMsg)
                        const _nodeList = swapListElements(nodeList, currentBottomNodeIndex, findIndex);
                        return _nodeList;
                    }
                    break;
                case 'up':
                    console.log("nodeList[findIndex - 1]--->", nodeList[findIndex - 1])
                    if (
                        nodeList[findIndex - 1] &&
                        nodeList[findIndex - 1].pid == targetNodePid
                    ) {
                        let currentChildrenNodeIndexList: number[] = [];
                        for (let i = 0; i < nodeList.length; i++) {
                            if (nodeList[i].pid == targetNodePid) {
                                if (i <= findIndex) {
                                    currentChildrenNodeIndexList.push(i)
                                }
                            }
                        }
                        console.log("currentChildrenNodeIndexList--->", currentChildrenNodeIndexList)
                        let _nodeList = nodeList;
                        // for (let i = 0; i < currentChildrenNodeIndexList.length; i++) {
                        //     if (i > 0) {
                        //         const currentNodeIndex = currentChildrenNodeIndexList[i];
                        //         const currentNodeAfterIndex = currentChildrenNodeIndexList[i - 1];
                        //         console.log("转换---->i", currentNodeIndex, currentNodeAfterIndex);
                        //         _nodeList = swapListElements(_nodeList, currentNodeAfterIndex, currentNodeIndex);
                        //     }
                        // }
                        _nodeList = swapListElements(_nodeList, currentChildrenNodeIndexList[currentChildrenNodeIndexList.length - 2], currentChildrenNodeIndexList[currentChildrenNodeIndexList.length - 1]);
                        toastShort('success', commonSuccessMsg)
                        return _nodeList;
                    } else {
                        toastShort('warning', '该节点已置顶，不可继续上移')
                    }
                    break;
                case 'down':
                    if (nodeList[findIndex + 1] && nodeList[findIndex + 1].pid == targetNodePid) {
                        toastShort('success', commonSuccessMsg)
                        const _nodeList = swapListElements(nodeList, findIndex, findIndex + 1);
                        return _nodeList;
                    } else {
                        toastShort('warning', '该节点已置底，不可继续下移')
                    }
                    break;
                default:
                    break;
            }
            return nodeList;
        } else {
            toastShort('error', '节点不存在，请您刷新页面重试！')
        }
    }

    const handleMoveCurrentSelectedNode = (moveType: 'up' | 'down' | 'top' | 'bottom') => {
        try {
            let _tempComDocInstance = tempComDocInstance.current;
            let _tempTopicList = _tempComDocInstance.topicList;
            _tempTopicList = moveNode(_tempTopicList, currentSelectedTopicNode.id, moveType);
            _tempTopicList = deepCloneV2(_tempTopicList);
            //更新topicList
            tempTopicList.current = _tempTopicList;
            //更新文档
            _tempComDocInstance.topicList = _tempTopicList;
            tempComDocInstance.current = _tempComDocInstance;
            handleUpdateComDocInstance(tempComDocInstance.current);
        } catch (e) {
            toastShort('error', commonErrorMsg)
        }
    }

    /**
     * 当选择1级contextMenu之后
     * @param actionType 
     */
    const onPickerTreeNodeActionType = (actionType: TopicNodeActionType) => {
        setCurrentTreeNodeActionType(actionType);
        switch (actionType) {
            case 'AddDeviceChildNode':
                // if(Number(currentSelectedTopicNode.topicLevel) >= 6){
                //     return toastShort('error', '大纲节点最多不能超过6级')
                // }
                addTopicModalRef.current.openModal();
                break;
            case 'AddTextChildNode':
                if (Number(currentSelectedTopicNode.topicLevel) >= 6) {
                    return toastShort('error', '大纲节点最多不能超过6级')
                }
                addTopicModalRef.current.openModal();
                break;
            case 'AddDevicePeerNode':
                addTopicModalRef.current.openModal();
                break;
            case 'AddTextPeerNode':
                addTopicModalRef.current.openModal();
                break;
            case 'MoveUp':
                handleMoveCurrentSelectedNode('up');
                break;
            case 'MoveDown':
                handleMoveCurrentSelectedNode('down');
                break;
            case 'MoveTop':
                handleMoveCurrentSelectedNode('top');
                break;
            case 'MoveBottom':
                handleMoveCurrentSelectedNode('bottom');
                break;
            case 'ReName':
                // renameTopicModalRef.current.openModal(currentSelectedTopicNode.topicName);
                break;
            case 'Delete':
                break;
            case 'UnChecked':
                handleUnCheckedCurrentSelectedNode();
                break;
            default:
                break;
        }
    }

    const handleUnCheckedCurrentSelectedNode = () => {
        modal.confirm({
            title: '温馨提示',
            icon: <ExclamationCircleOutlined />,
            content: '确认从本文大纲中移除此节点吗？移除后您可在大纲配置中重新勾选',
            okText: '确认',
            cancelText: '取消',
            centered: true,
            onOk: confirmToUnCheckedCurrentSelectedNode,
        });
    }

    const findAllDescendants = (treeData: TopicType[], nodeId: string) => {
        const result = [];
        function findDescendants(node) {
            if (!node || !node.children) return;
            node.children.forEach(child => {
                result.push(child.id);
                findDescendants(child);
            });
        }

        function findNodeAndDescendants(nodes) {
            for (let i = 0; i < nodes.length; i++) {
                if (nodes[i].id === nodeId) {
                    findDescendants(nodes[i]);
                    break;
                }
                if (nodes[i].children) {
                    findNodeAndDescendants(nodes[i].children);
                }
            }
        }
        findNodeAndDescendants(treeData);
        return result;
    }

    const currentTopicTree = () => {
        let _tempComDocInstance = tempComDocInstance.current;
        let { topicList } = _tempComDocInstance;
        let _tree = generateTreeData(addTreePropertyForList(topicList));
        _tree = filterTree(_tree, (node) => node.checked);
        let serialNumberList = [];
        dfsRecursive(_tree, (topic: TopicType, level: number) => {
            if (topic.topicType == 'text') {
                if (serialNumberList.length > level) {
                    serialNumberList = serialNumberList.splice(0, level + 1)
                    serialNumberList[serialNumberList.length - 1]++;
                } else if (serialNumberList.length == level) {
                    if (isEmpty(serialNumberList[level])) {
                        serialNumberList[level] = 1;
                    } else {
                        serialNumberList[level]++;
                    }
                } else {
                    serialNumberList.push(1)
                }
                const serialNumber = serialNumberList.join('.');
                topic.treeLevel = level;
                topic.serialNumber = serialNumber;
            }
        })
        const currentTopicTreeData: TopicType[] = deepCloneV2(_tree);
        console.log("currentTopicTreeData--->", deepCloneV2(currentTopicTreeData), deepCloneV2(topicList))
        return currentTopicTreeData;
    };

    const findTreePathByTargetNodeIdList = (treeData: TopicType[], nodeId: string) => {
        const map = new Map();
        // 建立每个节点与其父节点的映射
        function buildMap(node, parentId = null) {
            if (!node) return;
            map.set(node.id, parentId);
            if (node.children) {
                node.children.forEach(child => buildMap(child, node.id));
            }
        }
        // 遍历树数据，建立映射
        treeData.forEach(node => buildMap(node));
        // 从指定节点回溯到根节点
        const path = [];
        let currentId = nodeId;
        while (currentId !== null) {
            path.push(currentId);
            currentId = map.get(currentId);
        }
        return path.reverse(); // 反转数组，使其从根节点开始
    }


    const confirmToUnCheckedCurrentSelectedNode = () => {
        try {

            // //需要直接取消勾选的节点
            let needToUnCheckedIdList = findAllDescendants(currentTopicTree(), currentSelectedTopicNode.id);
            // //需要取消勾选的节点(如果此节点是勾选的话);
            let needToUnCheckedIfNodeChecedIdList = findTreePathByTargetNodeIdList(currentTopicTree(), currentSelectedTopicNode.id);
            // _checkedTopicIdList = _checkedTopicIdList.filter(id => {
            //     return id !== currentSelectedTopicNode.id && 
            //     // !needToUnCheckedIfNodeChecedIdList.includes(id) &&
            //     !needToUnCheckedIdList.includes(id)
            // });
            // onTreeNodeCheckedChange([..._checkedTopicIdList])
            let _tempComDocInstance = tempComDocInstance.current;
            let { topicList } = _tempComDocInstance;
            const tempTopicTreeData = generateTreeData(topicList);
            dfsRecursive(tempTopicTreeData, (node: TopicType) => {
                if (node.id == currentSelectedTopicNode.id) {
                    node.checked = false;
                }
                if (needToUnCheckedIdList.includes(node.id)) {
                    node.checked = false;
                }
                if (needToUnCheckedIfNodeChecedIdList.includes(node.id)) {
                    node.checked = false;
                }
            })
            _tempComDocInstance.topicList = deepCloneV2(tree2List(tempTopicTreeData));
            handleUpdateComDocInstance(_tempComDocInstance);
            toastShort('success', commonSuccessMsg)
        } catch (e) {
            toastShort('error', commonErrorMsg)
        }
    }

    const insertChildNodeListToTree = (tree: TopicType[], list: TopicType[], targetNodeId: string) => {
        tree.forEach(node => {
            if (node.id == targetNodeId) {
                list && list.length && list.forEach(item => {
                    item.pid = targetNodeId;
                })
                if (node.children && node.children.length) {
                    node.children = deepCloneV2(node.children.concat(list));
                } else {
                    node.children = deepCloneV2(list);
                }
                node = deepCloneV2(node);
            } else if (node.children && node.children.length) {
                insertChildNodeListToTree(node.children, list, targetNodeId)
            }
        })
        return deepCloneV2(tree);
    }

    const insertTopPeerNodeListToTree = (tree: TopicType[], list: TopicType[], targetNodeId: string) => {
        let findTopTagetNodeIndex = -1;
        tree.forEach((node, nodeIndex) => {
            if (node.id == targetNodeId) {
                findTopTagetNodeIndex = nodeIndex;
            }
        })
        list.forEach(item => {
            item.pid = '0';
        })
        let tempTreeData = tree;
        if (findTopTagetNodeIndex > -1) {
            const lastArr = tempTreeData.splice(findTopTagetNodeIndex + 1, tree.length - 1);
            tempTreeData = tempTreeData.concat(list).concat(lastArr)
        }
        return tempTreeData;
    }

    const insertPeerNodeListToTree = (tree: TopicType[], list: TopicType[], targetNodeId: string) => {
        list.forEach(topic => {
            topic.wordParagraphList = [];
        })
        tree.forEach((node, index, array) => {
            if (node.children && node.children.length) {
                let targetIndex = node.children.findIndex(subNode => subNode.id === targetNodeId);

                if (targetIndex !== -1) {
                    list.forEach(item => {
                        item.pid = node.id;
                    });
                    // 在目标节点的下一个位置插入新节点
                    node.children.splice(targetIndex + 1, 0, ...list);
                } else {
                    insertPeerNodeListToTree(node.children, list, targetNodeId);
                }
            }
        });
    };

    const _onFinish = (newTopic: TopicType) => {
        try {
            newTopic.checked = true;
            newTopic.isMainProject = false;
            newTopic.childrenDeviceTopicListLength = 0;
            let _tempComDocInstance = tempComDocInstance.current;
            let _tempTreeData = generateTreeData(_tempComDocInstance.topicList);
            // console.warn("excel界面节点更新前_tempTreeData---->", _tempTreeData, currentSelectedTopicNode.topicName)
            let newTopicNodeList = [newTopic];
            switch (currentTreeNodeActionType) {
                case 'AddDeviceChildNode':
                    _tempTreeData = insertChildNodeListToTree(_tempTreeData, newTopicNodeList, currentSelectedTopicNode.id)
                    break;
                case 'AddTextChildNode':
                    _tempTreeData = insertChildNodeListToTree(_tempTreeData, newTopicNodeList, currentSelectedTopicNode.id)
                    break;
                case 'AddDevicePeerNode':
                    if (currentSelectedTopicNode.pid == '0') {
                        _tempTreeData = insertTopPeerNodeListToTree(_tempTreeData, newTopicNodeList, currentSelectedTopicNode.id)
                    } else {
                        insertPeerNodeListToTree(_tempTreeData, newTopicNodeList, currentSelectedTopicNode.id)
                    }
                    break;
                case 'AddTextPeerNode':
                    if (currentSelectedTopicNode.pid == '0') {
                        _tempTreeData = insertTopPeerNodeListToTree(_tempTreeData, newTopicNodeList, currentSelectedTopicNode.id)
                    } else {
                        insertPeerNodeListToTree(_tempTreeData, newTopicNodeList, currentSelectedTopicNode.id)
                    }
                    break;
                default:
                    break;
            }
            const __tempTreeData = deepCloneV2(_tempTreeData);
            const __tempTopicList = deepCloneV2(tree2List(__tempTreeData));
            tempTopicList.current = __tempTopicList;
            _tempComDocInstance.topicList = __tempTopicList;
            tempComDocInstance.current = deepCloneV2(_tempComDocInstance);
            refreshExcelTableDataLocal();
            handleUpdateComDocInstance(tempComDocInstance.current);
            toastShort('success', commonSuccessMsg)
        } catch (e) {
            toastShort('error', commonErrorMsg)
        }
    }

    const onContextMenuClose = () => {
        excelEditorContextMenuIsOpen.current = false;
    }

    useEffect(() => {
        if (comDocConfig && comDocConfig.docExtraConfigInfo && comDocConfig.docExtraConfigInfo.excelColumnFillMode) {
            onFillMethodChange(comDocConfig.docExtraConfigInfo.excelColumnFillMode)
        }
    }, [comDocInstance]);

    const makeFullScreen = () => {
        var elem = document.getElementById("ExcelV2ContainerId");
        if (elem.requestFullscreen) {
            elem.requestFullscreen();
            //@ts-ignore
        } else if (elem.mozRequestFullScreen) { /* Firefox */
            //@ts-ignore
            elem.mozRequestFullScreen();
            //@ts-ignore
        } else if (elem.webkitRequestFullscreen) { /* Chrome, Safari & Opera */
            //@ts-ignore
            elem.webkitRequestFullscreen();
            //@ts-ignore
        } else if (elem.msRequestFullscreen) { /* IE/Edge */
            //@ts-ignore
            elem.msRequestFullscreen();
        }
    }

    return (
        <div
            id="ExcelV2ContainerId"
            ref={editorContainerRef}
            className="flex-col content-border content-border-radius new-excel-editor"
        >
            <div className='flex-col new-excel-editor-content'>
                <div
                    ref={excelContainerRef}
                    className="excel-layout-container"
                    onMouseUp={onExcelContainerMouseUp}
                    onContextMenu={onExcelContextMenu}
                >
                    {
                        excelInitialized ?
                            <LuckySheetWapper
                                ref={luckySheetWapperRef}
                                initExcelConfig={initExcelExtraConfig.current}
                                initCellDataList={cellDataList.current}
                                onCellValueChange={onCellValueChange}
                                onSheetScrollEnd={onSheetScrollEnd}
                                onRangeSelect={onRangeSelect}
                                onCellMousedown={onCellMousedown}

                            />
                            :
                            null
                    }
                    <LoadingWapper
                        ref={loadingWapperRef1}
                        title="刷新Excel数据中..."
                        loading
                        autoControl={false}
                    />
                    <LoadingWapper
                        ref={loadingWapperRef2}
                        title="刷新Excel数据中..."
                        loading
                        autoControl={false}
                    />
                </div>
                <div
                    className="flex-row excel-bottom-bar"
                >
                    <div className="flex-row excel-bottom-bar-left">
                        <div className="flex-row excel-bottom-switch-bar">
                            <VerticalRightOutlined />
                            <LeftOutlined />
                            <RightOutlined />
                            <VerticalLeftOutlined />
                        </div>
                        <div className="flex-row excel-file-list">
                            <div className="flex-row excel-file-item">投资估算表格</div>
                        </div>
                    </div>
                    {
                        excelInitialized && initExcelExtraConfig.current ?
                            <ExcelZoomKit
                                initZoomValue={initExcelExtraConfig.current.zoom}
                                initFillMode={comDocConfig && comDocConfig.docExtraConfigInfo.excelColumnFillMode || 'autoColumnWidth'}
                                onZoomChange={onZoomChange}
                                onFillMethodChange={onFillMethodChange}
                            />
                            :
                            null
                    }
                </div>
            </div>
            <AddTopicMoal
                ref={addTopicModalRef}
                currentTopicNode={currentSelectedTopicNode}
                currentTreeNodeActionType={currentTreeNodeActionType}
                onFinish={_onFinish}
            />
            <ExcelEditorContextMenu
                ref={contextMenuRef}
                onContextMenuClose={onContextMenuClose}
                currentTopicNode={currentSelectedTopicNode}
                onPickerActionType={onPickerTreeNodeActionType}
            />
            {contextHolder}
        </div>
    )
}


export default forwardRef(ExcelEditorV2);